#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;

class my_string
{
	friend istream& operator>>(istream& ci, my_string& s);
public:
	my_string(const char* s="")
	{
		_size = _capacity = strlen(s);
		_str = new char[_size + 1];
		strcpy(_str, s);
	}//实现了默认和带参构造
	//my_string(const my_string& s)
	//{
	//	_size = _capacity = strlen(s._str);
	//	_str = new char[_size + 1];
	//	strcpy(_str, s._str);

	//}//实现拷贝构造
	
	//拷贝构造的现代写法（使用swap)
	my_string(const my_string& s)
		:_str(nullptr) //如果初始化 换给s中的str后，s析构delete时就会出问题
	{
		my_string tmps(s._str);
		swap(tmps);
	}
	~my_string()
	{
		delete[] _str;
		_capacity = _size = 0;
		_str = nullptr;
	}
	char& operator[](size_t pos)const
	{
		assert(pos >= 0 && pos < _size);
		return *(_str + pos);
	}
	typedef char* iterator;

	char* begin()const
	{
		return _str;
	}

	char* end()const
	{
		return _str + _size ;
	}

	void push_back(char c)
	{
		if (_capacity == _size)
		{
			size_t capacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(capacity);
		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	void append(const char* s)
	{
		size_t len = strlen(s);
		if (_size + len > _capacity)
		{
			size_t capacity =  _size + len;
			reserve(capacity);
		}
		strcpy(_str + _size, s);
		_size = _size + len;
	}
	void operator+=(char c)
	{
		push_back(c);
	}
	void operator+=(const char* str)
	{
		append(str);
	}
	void reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[] _str;
			_str = tmp;
			_capacity = n;
		}
	}
	void resize(size_t n,char c = '\0')
	{
		if (n <= _size)
		{
			_str[n] = '\0';
		}
		else
		{
			reserve(n);
			for (size_t i = _size; i < n; i++)
			{
				_str[i] = c;
			}
			_str[n] = '\0';
		}
	}
	my_string& insert(size_t pos, size_t n, char c)
	{
		assert(pos <= _size);
		if (_capacity < _size + n)
		{
			reserve(_size + n);
		}//先增容
		int end = _size;
		while (end >= (int)pos)
		{
			_str[end + n] = _str[end];
			end--;
		}//将pos位置后的移动，腾出n个位置
		while (n)
		{
			_str[pos] = c;
			pos++;
			n--;
		}
		return *this;
	}
	my_string& insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t len = strlen(str);
		if (_capacity < _size + len)
		{
			reserve(_size + len);
		}//扩容
		int end = _size;
		while (end >= (int)pos)
		{
			_str[end + len] = _str[end];
			end--;
		}//腾位置
		strncpy(_str + pos, str, len);
		return *this;
	}

	my_string erase(size_t pos, size_t len = npos)
	{
		assert(pos < _size);
		if (len >= _size - pos)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			for (size_t i = pos + len; i <= _size; i++)
			{
				_str[i - len] = _str[i];
			}
		}
		return *this;
	}
	size_t find(char c, size_t pos = 0)const
	{
		assert(pos < _size);
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == c)
			{
				return i;
			}
		}
		return npos;
	}
	size_t find(const char* str, size_t pos = 0)const
	{
		assert(pos < _size);
		const char* s = strstr(_str + pos, str);
		if (s)
		{
			return s - begin();
		}
		return npos;
	}
	//my_string& operator=(const my_string& s)
	//{
	//	delete[] _str;
	//	char* tmp = new char[strlen(s._str) + 1];
	//	strcpy(tmp, s._str);
	//	_str = tmp;
	//	return *this;
	//}

	// operator=的现代写法(使用swap）

	///*my_string & operator=(const my_string & s)
	//{
	//	my_string s1(s);
	//	swap(s1);
	//}*/
	my_string& operator=(my_string s)
	{
		swap(s);
		return *this;
	}
	bool operator==(const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c == 0;
	}
	bool operator> (const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c > 0;
	}
	bool operator< (const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c < 0;
	}
	bool operator>=(const my_string& s)const
	{
		return !(*this < s);
	}
	bool operator<=(const my_string& s)const
	{
		return !(*this > s);
	}
	size_t size()const
	{
		return _size;
	}
	size_t capacity()const
	{
		return _capacity;
	}

	char* c_str() const
	{
		return _str;
	}
	void swap(my_string& s)
	{
		::swap(_str, s._str); //_str指向的是地址，所以库的swap实现了首元素地址交换，就交换了整个
		::swap(_size, s._size);
		::swap(_capacity, s._capacity);
	}
private:
	char* _str;
	size_t _size;//已经有多少有效字符
	size_t _capacity;//能存储多少有效字符

	static size_t npos;
};

size_t my_string::npos = -1;

ostream& operator<<(ostream& cou, const my_string& s)
{
	cout << s.c_str();
	return cou;
}
istream& operator>>(istream& ci, my_string& s)
{
	while (1)
	{
		char c;
		c=ci.get();
		if (c == '\0' || c == '\n')
		{
			break;
		}
		else
		{
			s.push_back(c);
		}
	}
	return ci;
	
}//利用istream中的get获取单个字符

int main()
{
	/*my_string s;
	my_string s1("claus hello");
	my_string s2(s1);
	cout << s.c_str()<<endl;
	cout << s1.c_str() << endl;
	cout << s2.c_str() << endl;
	cout << s2[10] << endl;
	cout << s1 << s2 << endl;*/
	/*my_string s("hello claus");*/
	/*for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << " ";
	}
	cout << endl;
	for (int i = 0; i < s.size(); i++)
	{
		s[i] += 1;
		cout << s[i] << " ";
	}
	cout << endl;
	my_string::iterator it = s.begin();
	while (it<s.end())
	{
		*it -= 1;
		cout << *it;
		++it;
	}
	cout << endl;
	for (auto& i : s)
	{
		i += 1;
		cout << i;
	}*/
	//my_string  s("claus hello");
	//cout << s << endl;
	//s.push_back('k');
	//cout << s << endl;
	//s.append(" wiedersehen");
	//cout << s << endl;
	//s += "claus";
	//s += '0';
	//s += " ";
	//cout << s << endl;
	//my_string s2;
	//s2 = s;
	//cout << s2 << endl;
	my_string s("claus hello");
	my_string s1(s);
	my_string s2;
	s2 = s1;
	cout << s2 ;
	return 0;
}